package com.ye.personnel.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ye.personnel.api.ChangeStatusDto;
import com.ye.personnel.api.department.DepartmentListFrListSearch;
import com.ye.personnel.api.department.DepartmentListFrVo;
import com.ye.personnel.api.department.DepartmentTreeVo;
import com.ye.personnel.api.department.SaveDepartmentNumDto;
import com.ye.personnel.api.enums.UserTypeEnum;
import com.ye.personnel.api.gwy.GwyMemberListVo;
import com.ye.personnel.api.gwy.MemberListByDepartmentNoSearch;
import com.ye.personnel.api.user.AdminUserListVo;
import com.ye.personnel.api.user.AdminUserSetDto;
import com.ye.personnel.api.user.ChangeUserPasswordDto;
import com.ye.personnel.common.exception.CustomerException;
import com.ye.personnel.common.page.BasePageParam;
import com.ye.personnel.common.page.PageModel;
import com.ye.personnel.common.response.ErrorCode;
import com.ye.personnel.common.utils.JwtUtil;
import com.ye.personnel.common.utils.PasswordUtils;
import com.ye.personnel.mapper.dao.GwyAdminUserMapper;
import com.ye.personnel.mapper.dao.GwyDepartmentMapper;
import com.ye.personnel.mapper.entity.GwyAdminUser;
import com.ye.personnel.mapper.entity.GwyDepartment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: yeubo
 * @Date: 2024/1/2 11:42
 */
@Service
@Slf4j
public class UserService {

    @Autowired
    GwyAdminUserMapper adminUserMapper;
    @Autowired
    GwyDepartmentMapper departmentMapper;
    @Autowired
    GwyCmsSystemService gwyCmsSystemService;

    /**
     * 用户列表分页
     * @param params
     * @return
     */
    public PageModel<AdminUserListVo> userList(BasePageParam params){

        Page<GwyAdminUser> rowPage = new Page<>(params.getPage(), params.getPageSize());
        LambdaQueryWrapper<GwyAdminUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(params.getSearchBody()),GwyAdminUser::getNickName,params.getSearchBody());
        Page<GwyAdminUser> page = adminUserMapper.selectPage(rowPage,queryWrapper);
        List<GwyAdminUser> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(page, new ArrayList<>());
        }
        List<AdminUserListVo> list = BeanUtil.copyToList(records, AdminUserListVo.class);
        for (AdminUserListVo userListVo : list){
            GwyDepartment department = departmentMapper.selectById(userListVo.getDepartmentId());
            userListVo.setDepartmentName(department != null ? department.getDepartmentName() : "");
            String userTypeName = UserTypeEnum.getName(userListVo.getUserType());
            userListVo.setUserTypeName(userTypeName);
        }
        return new PageModel<>(page, list);
    }


    /**
     * 用户详情
     * @param adminUserId
     * @return
     */
    public AdminUserListVo userDetail(String adminUserId){
        GwyAdminUser user = adminUserMapper.selectById(adminUserId);
        AdminUserListVo userInfo = BeanUtil.copyProperties(user, AdminUserListVo.class);
        String departmentId = userInfo.getDepartmentId();
        GwyDepartment department = departmentMapper.selectById(departmentId);
        if(department != null){
            userInfo.setDepartmentName(department.getDepartmentName());
        }
        return userInfo;
    }

    /**
     * 添加用户
     * @param params
     * @return
     */
    public boolean setUser(AdminUserSetDto params){
        String adminUserId = params.getAdminUserId();
        LambdaQueryWrapper<GwyAdminUser> queryWrapper = new QueryWrapper<GwyAdminUser>().lambda();
        queryWrapper.eq(GwyAdminUser::getNickName,params.getUserName());
        if(StringUtils.isNotEmpty(adminUserId)){
            queryWrapper.ne(GwyAdminUser::getAdminUserId,adminUserId);
        }
        long brandExist = adminUserMapper.selectCount(queryWrapper);
        if(brandExist > 0){
            throw new CustomerException(ErrorCode.PARAMS_GET_ERROR,"用户登录账号重复");
        }
        try {
            GwyAdminUser adminUser = BeanUtil.copyProperties(params, GwyAdminUser.class);
            String password = PasswordUtils.encode("123456");
            adminUser.setPassword(password);
            if(StringUtils.isEmpty(adminUserId)){
                return adminUserMapper.insert(adminUser) > 0;
            }else{
                return adminUserMapper.updateById(adminUser) > 0;
            }
        } catch (Exception e) {
            log.info("设置用户失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 重置用户密码
     * @return
     */
    public boolean resetUserPassword(String adminUserId){
        GwyAdminUser user = adminUserMapper.selectById(adminUserId);
        if(user == null){
            throw new CustomerException(ErrorCode.PARAMS_GET_ERROR,"用户不存在");
        }
        String password = PasswordUtils.encode("123456");
        user.setPassword(password);
        int update = adminUserMapper.updateById(user);
        return update > 0;
    }

    /**
     * 修改密码
     * @param passwordDto
     * @return
     */
    public boolean changeUserPassword(ChangeUserPasswordDto passwordDto){
        if(!Objects.equals(passwordDto.getNewPassword(), passwordDto.getConfirmPassword())){
            throw new CustomerException(ErrorCode.PARAMS_GET_ERROR,"2次密码输入不一致，请重新输入");
        }
        String loginId = JwtUtil.getLoginId();
        GwyAdminUser adminUser = adminUserMapper.selectById(loginId);
        if(adminUser == null){
            throw new CustomerException(ErrorCode.TOKEN_INVALID,"登录失效，请重新登录");
        }
        if(!Objects.equals(adminUser.getPassword(), passwordDto.getOriginalPassword())){
            throw new CustomerException(ErrorCode.PARAMS_GET_ERROR,"原密码错误，请重新输入");
        }
        adminUser.setPassword(passwordDto.getNewPassword());
        int update = adminUserMapper.updateById(adminUser);
        return update > 0;
    }

    /**
     * 删除用户
     * @param adminUserId
     * @return
     */
    public boolean deleteUser(String adminUserId){
        try {
            int delete = adminUserMapper.deleteById(adminUserId);
            return delete > 0;
        } catch (Exception e) {
            log.info("deleteUser error:" + e.getMessage());
        }
        return false;
    }

    /**
     *
     * @param statusDto
     * @return
     */
    public boolean changeStatus(ChangeStatusDto statusDto){
        String targetId = statusDto.getTargetId();
        GwyAdminUser user = adminUserMapper.selectById(targetId);
        if(user == null){
            throw new CustomerException(ErrorCode.PARAMS_GET_ERROR,"用户不存在");
        }
        try {
            GwyAdminUser adminUser = new GwyAdminUser();
            adminUser.setAdminUserId(user.getAdminUserId());
            adminUser.setDisabled(statusDto.getTargetStatus());
            int update = adminUserMapper.updateById(adminUser);
            return update > 0;
        } catch (Exception e) {
            String message = e.getMessage() == null ? Arrays.toString(e.getStackTrace()) : e.getMessage();
            log.info("changeStatus error:" + message);
        }
        return false;
    }

    /**
     * 单位树
     * @param parentDepartmentId
     * @return
     */
    public List<DepartmentTreeVo> departmentTree(String parentDepartmentId){
        String parentId = StringUtils.isBlank(parentDepartmentId) ? "" : parentDepartmentId;
        LambdaQueryWrapper<GwyDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GwyDepartment::getParentDepartmentId,parentId);
        queryWrapper.orderByDesc(GwyDepartment::getCreatedTime);
        List<GwyDepartment> departmentList = departmentMapper.selectList(queryWrapper);
        List<DepartmentTreeVo> departmentTree = BeanUtil.copyToList(departmentList, DepartmentTreeVo.class);
        for (DepartmentTreeVo department : departmentTree){
            if(StringUtils.isNotBlank(department.getDepartmentId())){
                List<DepartmentTreeVo> departmentTreeVos = departmentTreeChildren(department.getDepartmentId());
                department.setChildrenDepartment(departmentTreeVos);
            }
        }
        return departmentTree;
    }

    /**
     * 单位id
     * @param parentDepartmentId
     * @return
     */
    public List<String> departmentTreeIds(String parentDepartmentId){
        String parentId = StringUtils.isBlank(parentDepartmentId) ? "" : parentDepartmentId;
        LambdaQueryWrapper<GwyDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GwyDepartment::getParentDepartmentId,parentId);
        queryWrapper.orderByDesc(GwyDepartment::getCreatedTime);
        List<GwyDepartment> departmentList = departmentMapper.selectList(queryWrapper);
        List<String> ids = departmentList.stream()
                .map(GwyDepartment::getDepartmentId).collect(Collectors.toList());
        for (String departmentId : ids){
            if(StringUtils.isNotBlank(departmentId)){
                List<String> departmentIds = departmentTreeChildrenId(departmentId);
                ids.addAll(departmentIds);
            }
        }
        return ids;
    }



    /**
     * 设置部门编制人数
     * @param saveDepartmentNumDto
     * @return
     */
    public boolean saveDepartmentNum(SaveDepartmentNumDto saveDepartmentNumDto){
        String departmentId = saveDepartmentNumDto.getDepartmentId();
        GwyDepartment department = departmentMapper.selectById(departmentId);
        if(department == null){
            throw new CustomerException(ErrorCode.PARAMS_GET_ERROR,"机构不存在");
        }
        GwyDepartment gwyDepartment = BeanUtil.copyProperties(saveDepartmentNumDto, GwyDepartment.class);
        int update = departmentMapper.updateById(gwyDepartment);
        return update > 0;
    }

    /**
     * 法人单位列表
     * @param params
     * @return
     */
    public List<DepartmentListFrVo> departmentListFrTree(DepartmentListFrListSearch params){
        String loginId = JwtUtil.getLoginId();
        GwyAdminUser adminUser = adminUserMapper.selectById(loginId);
        if(adminUser == null){
            throw new CustomerException(ErrorCode.TOKEN_INVALID,"登录失效，请重新登录");
        }
        LambdaQueryWrapper<GwyDepartment> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(params.getDepartmentName())){
            queryWrapper.like(GwyDepartment::getDepartmentName,params.getDepartmentName());
        }
        String parentDepartmentId = params.getParentDepartmentId();
        if(StringUtils.isBlank(parentDepartmentId)){
            String departmentId = JwtUtil.getDepartmentId();
            if(adminUser.getAdminStatus() == 1){
                GwyDepartment department = departmentMapper.selectOne(new LambdaQueryWrapper<GwyDepartment>()
                        .eq(GwyDepartment::getDepartmentNo, "001.001")
                        .last("limit 1"));
                if(department != null){
                    departmentId = department.getDepartmentId();
                }
            }
            queryWrapper.eq(GwyDepartment::getParentDepartmentId,departmentId);
        }else{
            queryWrapper.eq(GwyDepartment::getParentDepartmentId,parentDepartmentId);
        }
        queryWrapper.eq(GwyDepartment::getDepartmentType,1);
        queryWrapper.orderByDesc(GwyDepartment::getCreatedTime);
        List<GwyDepartment> departmentLists = departmentMapper.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(departmentLists)){
            return new ArrayList<>();
        }
        List<DepartmentListFrVo> list = BeanUtil.copyToList(departmentLists, DepartmentListFrVo.class);
        for (DepartmentListFrVo departmentList : list){
            String departmentNo = departmentList.getDepartmentNo();
            //全部
            Integer all = gwyCmsSystemService.getDepartmentPositionRealNum(departmentNo, null);
            departmentList.setDepartmentNumReal(all);
            //正科
            Integer zk = gwyCmsSystemService.getDepartmentPositionRealNum(departmentNo, "23");
            departmentList.setDepartmentNumZkReal(zk);
            departmentList.setDepartmentNumZkDiff(departmentList.getDepartmentNumZk()-zk);
            //副科
            Integer fk = gwyCmsSystemService.getDepartmentPositionRealNum(departmentNo, "24");
            departmentList.setDepartmentNumFkReal(fk);
            departmentList.setDepartmentNumFkDiff(departmentList.getDepartmentNumFk()-fk);
            //一级二级科员
            Integer ky = gwyCmsSystemService.getDepartmentPositionRealNumSec(departmentNo, "17","18");
            departmentList.setDepartmentNumKyReal(ky);
            departmentList.setDepartmentNumKyDiff(departmentList.getDepartmentNumKy()-ky);
            //三级四级科员
            Integer kySec = gwyCmsSystemService.getDepartmentPositionRealNumSec(departmentNo, "19","1A");
            departmentList.setDepartmentNumKySecReal(kySec);
            departmentList.setDepartmentNumKySecDiff(departmentList.getDepartmentNumKySec()-kySec);
        }
        return list;
    }


    /**
     * 法人单位列表
     *
     * @param params
     * @return
     */
    public PageModel<DepartmentListFrVo> departmentListFr(DepartmentListFrListSearch params){

        String departmentId = JwtUtil.getDepartmentId();

        Page<GwyDepartment> rowPage = new Page<>(params.getPage(), params.getPageSize());

        LambdaQueryWrapper<GwyDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GwyDepartment::getDepartmentType,1);
        if(StringUtils.isNotBlank(params.getDepartmentName())){
            queryWrapper.like(GwyDepartment::getDepartmentName,params.getDepartmentName());
        }
        queryWrapper.eq(GwyDepartment::getDepartmentId,departmentId);
        queryWrapper.orderByDesc(GwyDepartment::getCreatedTime);

        Page<GwyDepartment> pageMode = departmentMapper.selectPage(rowPage, queryWrapper);
        List<GwyDepartment> records = pageMode.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return new PageModel<>(pageMode, Collections.emptyList());
        }
        List<DepartmentListFrVo> list = BeanUtil.copyToList(records, DepartmentListFrVo.class);
        for (DepartmentListFrVo departmentList : list){
            String departmentNo = departmentList.getDepartmentNo();
            //全部
            Integer all = gwyCmsSystemService.getDepartmentPositionRealNum(departmentNo, null);
            departmentList.setDepartmentNumReal(all);
            //正科
            Integer zk = gwyCmsSystemService.getDepartmentPositionRealNum(departmentNo, "23");
            departmentList.setDepartmentNumZkReal(zk);
            departmentList.setDepartmentNumZkDiff(departmentList.getDepartmentNumZk()-zk);
            //副科
            Integer fk = gwyCmsSystemService.getDepartmentPositionRealNum(departmentNo, "24");
            departmentList.setDepartmentNumFkReal(fk);
            departmentList.setDepartmentNumFkDiff(departmentList.getDepartmentNumFk()-fk);
            //一级二级科员
            Integer ky = gwyCmsSystemService.getDepartmentPositionRealNumSec(departmentNo, "17","18");
            departmentList.setDepartmentNumKyReal(ky);
            departmentList.setDepartmentNumKyDiff(departmentList.getDepartmentNumKy()-ky);
            //三级四级科员
            Integer kySec = gwyCmsSystemService.getDepartmentPositionRealNumSec(departmentNo, "19","1A");
            departmentList.setDepartmentNumKySecReal(kySec);
            departmentList.setDepartmentNumKySecDiff(departmentList.getDepartmentNumKySec()-kySec);
        }
        return new PageModel<>(pageMode,list);
    }

    /**
     * 部门列表
     * @param parentDepartmentId
     * @return
     */
    public List<String> departmentIds(String parentDepartmentId){
        return null;
    }

    /**
     * 部门下的人员列表
     * @param search
     * @return
     */
    public PageModel<GwyMemberListVo> memberListByDepartmentNo(MemberListByDepartmentNoSearch search){
        return gwyCmsSystemService.memberListByDepartmentNo(search);
    }

    /**
     * 子单位
     * @param parentId
     * @return
     */
    public List<DepartmentTreeVo> departmentTreeChildren(String parentId){
        LambdaQueryWrapper<GwyDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GwyDepartment::getParentDepartmentId, parentId);
        queryWrapper.orderByDesc(GwyDepartment::getCreatedTime);
        List<GwyDepartment> departmentList = departmentMapper.selectList(queryWrapper);
        return BeanUtil.copyToList(departmentList, DepartmentTreeVo.class);
    }

    /**
     * 子单位id列表
     * @param parentDepartmentId
     * @return
     */
    public List<String> departmentTreeChildrenId(String parentDepartmentId){
        LambdaQueryWrapper<GwyDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GwyDepartment::getParentDepartmentId, parentDepartmentId);
        queryWrapper.eq(GwyDepartment::getDepartmentType,1);
        queryWrapper.orderByDesc(GwyDepartment::getCreatedTime);
        List<GwyDepartment> departmentList = departmentMapper.selectList(queryWrapper);
        return departmentList.stream().map(GwyDepartment::getDepartmentId).collect(Collectors.toList());
    }
}
